package com.tanhua.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.common.vo.PicUploadResult;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VoiceApi;
import com.tanhua.dubbo.pojo.UserInfo;
import com.tanhua.dubbo.pojo.Voice;
import com.tanhua.server.vo.VoiceVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.tanhua.dubbo.enums.SexEnum.MAN;

@Service
@Slf4j
@EnableScheduling
public class VoiceService {

    // 设置默认每天可以使用桃花传音的次数,
    private final Integer remainingTimes = 5;


    @DubboReference(version = "1.0.0")
    private VoiceApi voiceApi;

    @Autowired
    private VoiceMQService voiceMQService;

    @DubboReference(version = "1.0.0")
    private UserInfoApi userInfoApi;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private VoiceUploadService voiceUploadService;

    public Object saveVoice(MultipartFile voiceFile) {

        Long userId = UserThreadLocal.get();
        Voice voice = new Voice();
        voice.setUserId(userId);


        PicUploadResult uploadResult = voiceUploadService.upload(voiceFile);
        voice.setSoundUrl(uploadResult.getName());

        String voiceId = this.voiceApi.saveVideo(voice);
        if (StrUtil.isEmpty(voiceId)) {
            return ErrorResult.builder().errCode("502")
                    .errMessage("保存音频数据失败，请重试！").build();
        }

        //发送发布成功的消息
        //this.voiceMQService.voiceMsg(voiceId);

        return null;
    }

    public Object receiveVoice() {

        //当前用户的id
        Long myId = UserThreadLocal.get();

        //根据id查询当日次数，如果还剩余次数可以执行，如果次数用完直接返回信息
        // 用了一次桃花传音的机会就更新一次减一
        String remainingTimesStr = this.redisTemplate.opsForValue().get("VOICE_RESET_TIMES_" + myId);

        //初次使用的用户创建redisKey,同时初始化次数
        if (remainingTimesStr == null ){
            this.redisTemplate.opsForValue().set("VOICE_RESET_TIMES_" + myId,remainingTimes + "");
            remainingTimesStr = remainingTimes.toString();
        }

        //今日次数使用完
        if (Integer.valueOf(remainingTimesStr).equals(0)) {
            return "当日次数已用完";
        }



        Integer remainingTimes = Integer.parseInt(remainingTimesStr) - 1;
        this.redisTemplate.opsForValue().set("VOICE_RESET_TIMES_" + myId, remainingTimes + "");


        //剩余次数大于0
        Voice voiceInfo = this.voiceApi.receiveRecommendVoice(myId);
        if (voiceInfo == null){
            return "当前没有语音信息，请稍后再试";
        }


        //根据id查询发送该语音的用户信息
        UserInfo userInfo = this.userInfoApi.queryByUserId(voiceInfo.getUserId());

        //封装到voiceVo中进行返回
        VoiceVo voiceVo = BeanUtil.toBeanIgnoreError(voiceInfo, VoiceVo.class);
        BeanUtil.copyProperties(userInfo, voiceVo, "id", "userId");

        voiceVo.setGender((userInfo.getSex()== MAN)?"man":"woman");
        voiceVo.setId(Convert.toInt(userInfo.getUserId()));
        voiceVo.setRemainingTimes(remainingTimes);

        return voiceVo;

    }



    //每天凌晨0点执行一次
    @Scheduled(cron = "0 0 0 * * ?")
    private void configureTasks() {

        log.info("桃花传音每日定期复位用户使用桃花传音的次数");
        log.info("执行静态定时任务时间(每24小时执行一次): " + LocalDateTime.now());

        //查询用户，更新次数
        List<Voice> voiceList = this.voiceApi.queryAllVoice();
        ArrayList<Object> idList = new ArrayList<>();
        for (Voice voice : voiceList) {
            Long userId = voice.getUserId();
            idList.add(userId);
        }
        if (CollUtil.isEmpty(idList)){
            return;
        }
        List<UserInfo> userInfoList = this.userInfoApi.queryByUserIdList(idList);
        Set<Long> userInfoIds = userInfoList.stream().map(UserInfo::getUserId).collect(Collectors.toSet());

        for (Long userInfoId : userInfoIds) {
            // 复位为每天指定次数
            redisTemplate.opsForValue().set("VOICE_RESET_TIMES_" + userInfoId, remainingTimes + "", 1, TimeUnit.DAYS);

        }
    }
}
